package com.ktwlsoft.fundmanage.controller;

import com.ktwlsoft.fundmanage.domain.business.FundInService;
import com.ktwlsoft.fundmanage.domain.entity.FundInRecord;
import com.ktwlsoft.fundmanage.domain.entity.FundSuperviseAccept;
import com.ktwlsoft.fundmanage.domain.entity.BaseFundRecord.State;
import com.ktwlsoft.fundmanage.payload.BaseResult;
import com.ktwlsoft.fundmanage.payload.IAccountUser;
import com.ktwlsoft.fundmanage.payload.ResultType;
import com.ktwlsoft.fundmanage.payload.Contract.EditContractRequest;
import com.ktwlsoft.fundmanage.payload.fundIn.*;
import com.ktwlsoft.fundmanage.utils.UserUtils;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * 资金流程操作控制器，涵盖所有流程相关的操作Api
 *
 * @author LanJian
 */
@Api(description = "业务办理和资金交款, 作者：兰坚")
@RequestMapping("/flow")
@RestController
public class FlowInController {

    private final FundInService fundInService;

    public FlowInController(FundInService fundInService) {
        this.fundInService = fundInService;
    }

    @ApiOperation("检测网签是否存在")
    @GetMapping("/checkBusiness")
    public ResponseEntity<?> checkBusiness(@RequestParam String netWorkSign) {
        return ResponseEntity.ok(fundInService.checkBusiness(netWorkSign));
    }

    /**
     * 业务受理，提交新的案件或者编辑已存在的案件。 注意保存数据前，检查是否已经存在同样的网签编号。
     * 
     * @param fundSuperviseAccept
     * @return
     */
    @ApiOperation("新增/编辑案件")
    @PostMapping("/start")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<?> startFlow(@RequestBody FundSuperviseAccept fundSuperviseAccept) {
        BaseResult flowCheckResult;
        if (fundSuperviseAccept.getTsCode() > 0) {
            flowCheckResult = fundInService.update(fundSuperviseAccept);
        } else {
            flowCheckResult = fundInService.save(fundSuperviseAccept);
        }
        return ResponseEntity.ok(flowCheckResult);
    }

    @ApiOperation("资金录入")
    @PostMapping("/{tsCode}/saveFundIn")
    public ResponseEntity<?> saveFundIn(@RequestBody @Valid FundInRecord fundInRecord, @PathVariable long tsCode) {
        BaseResult result = fundInService.saveFund(fundInRecord);
        if (result.getResultType() == ResultType.BUSINESS_ERROR) {
            return ResponseEntity.status(HttpStatus.CONFLICT).body(result);
        }
        Map<String, Object> variables = new HashMap<>();
        variables.put("fundInRecord", fundInRecord);
        // payInFlowService.startProcess("KTWL-FUND-MANAGE-PAY-IN", variables);
        return ResponseEntity.ok(BaseResult.ok("Record In Success!"));
    }

    @ApiOperation("入账对账")
    @PostMapping("/fundInAccountCheck")
    public ResponseEntity<?> fundInAccountCheck(@RequestBody FundInAccountCheckRequest request) {
        try {
            IAccountUser user = UserUtils.getUser();
            if (user == null) {
                throw new Exception("未获取到用户！");
            }
            // List<String> roles = UserUtils.getRoles();
            // Task task = payInFlowService.getRoleTask(roles, "Pay In Check",
            // request.getInstanceId());
            // Map<String, Object> variable = new HashMap<>();
            // variable.put("fundInCheck", request.isApproval());
            BaseResult checkResult = fundInService.fundInAccountCheck(request.isApproval(), request.getFCode(),
                    user.getName(), user.getUserId(), request.getTsCode(), State.NORMAL,
                    request.getCheckTime());
            if (checkResult.getResultType() != ResultType.BUSINESS_SUCCESS) {
                return ResponseEntity.status(HttpStatus.CONFLICT).body(checkResult.getMessage());
            }
            // payInFlowService.completeTask(task.getId(), variable);
            return ResponseEntity.ok(BaseResult.ok("任务完成"));
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage(ex.getMessage()));
        }
    }

    @ApiOperation("入账修改")
    @PutMapping("/fundInModify")
    public ResponseEntity<?> fundInModify(@RequestBody FundInRecord record) {
        try {
            // List<String> roles = UserUtils.getRoles();
            // Task task = payInFlowService.getRoleTask(roles, "Modify Fund In",
            // record.getFlowInstanceId());
            // MUST SET THIS FALSE, CUS THIS FUND RECORD HAS BEEN MODIFIED.
            record.setPayCheck(false);
            fundInService.saveFund(record);
            // payInFlowService.completeTask(task.getId(), null);
            return ResponseEntity.ok(BaseResult.ok("修改完成"));
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage(ex.getMessage()));
        }
    }

    @ApiOperation("保存协议")
    @PostMapping("/saveProtocol")
    public ResponseEntity<?> saveBusinessProtocol(@RequestBody EditContractRequest protocol) {
        return ResponseEntity.ok(fundInService.saveProtocol(protocol));
    }

    @ApiOperation("获取协议")
    @GetMapping("/getProtocol")
    public ResponseEntity<?> findProtocol(long tsCode) {
        return ResponseEntity.ok(fundInService.findBusinessProtocal(tsCode));
    }

    @ApiOperation("合同审核")
    @PutMapping("/contractApproval")
    public ResponseEntity<?> contractApproval(@RequestBody ContractApprovalRequest request) {
        try {
            IAccountUser user = UserUtils.getUser();
            if (user == null) {
                throw new Exception("未获取到用户！");
            }
            fundInService.setContractApprovel(request, user.getName(), user.getUserId());
            return ResponseEntity.ok(BaseResult.ok("Task completed!"));
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage(ex.getMessage()));
        }
    }

    @ApiOperation("打印协议")
    @PutMapping("/printContract")
    public ResponseEntity<?> printContract(@RequestBody PrintContractRequest request) throws Exception {
        return ResponseEntity.ok(fundInService.printContract(request));
    }

    @ApiOperation("取消对账")
    @PutMapping("/cancelFundIn")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<?> cancelAccountCheck(@RequestBody CancelFundInRequest request) {
        try {
            // ProcessInstance instance =
            // cancelFundInFlowService.startProcess("KTWL-FUND-MANAGE-PAY-CANCEL");
            if (fundInService.cancelFundInCheck(request.getFCode(), null, request.getCancelReson())
                    .getResultType() == ResultType.BUSINESS_SUCCESS) {
                return ResponseEntity.ok(BaseResult.ok("取消对账！"));
            } else {
                return ResponseEntity.ok(BaseResult.body("", ResultType.BUSINESS_ERROR).withMessage("未能取消对账！"));
            }
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage(ex.getMessage()));
        }

    }

    @ApiOperation("取消对账后退回")
    @PutMapping("/afterCancelFundInTurnBack")
    public ResponseEntity<?> cancelFundIn(@RequestBody CancelFundInRequest request) {
        return ResponseEntity.ok(fundInService.turnBackFundIn(request));
    }

    @ApiOperation("取消对账后的对账")
    @PutMapping("/afterCancelFundInCheckChoose")
    public ResponseEntity<?> afterCancelFundInAccountChcek(@RequestBody FundInAccountCheckRequest request) {
        try {
            // FundInRecord fundInRecord =
            // fundInService.findFundInResult(request.getFCode());
            IAccountUser user = UserUtils.getUser();
            // List<String> roles = UserUtils.getRoles();
            // Task task = cancelFundInFlowService.getRoleTask(roles, "Check",
            // fundInRecord.getFlowInstanceId());
            // Map<String, Object> variable = new HashMap<>();
            // variable.put("approval", request.isApproval());
            BaseResult baseResult = fundInService.fundInAccountCheck(request.isApproval(), request.getFCode(),
                    user.getName(), user.getUserId(), request.getTsCode(), State.CANCEL_HANDLED,
                    request.getCheckTime());
            if (baseResult.getResultType() == ResultType.BUSINESS_SUCCESS) {
                // cancelFundInFlowService.completeTask(task.getId(), variable);
                return ResponseEntity.ok(BaseResult.ok("Fund in check completed!"));
            } else {
                return ResponseEntity.status(HttpStatus.CONFLICT)
                        .body(BaseResult.body(baseResult.getMessage(), ResultType.BUSINESS_ERROR));
            }
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage(ex.getMessage()));
        }
    }

    @ApiOperation("取消对账后修改入账")
    @PutMapping("afterCancelFundInModify")
    public ResponseEntity<?> afterCancelFundInModify(@RequestBody FundInRecord record) {
        try {
            // List<String> roles = UserUtils.getRoles();
            // Task task = cancelFundInFlowService.getRoleTask(roles, "Modify Fund In",
            // record.getFlowInstanceId());
            record.setPayCheck(false);
            record.setState(State.CANCEL_HANDLED);
            BaseResult result = fundInService.saveFundDirec(record);
            if (result.getResultType() == ResultType.BUSINESS_ERROR) {
                return ResponseEntity.status(HttpStatus.CONFLICT).body(result.getMessage());
            }
            // cancelFundInFlowService.completeTask(task.getId(), null);
            return ResponseEntity.ok(BaseResult.ok("Fund in check completed!"));
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage(ex.getMessage()));
        }
    }

    @ApiOperation("业务作废")
    @PutMapping("/businessCancel")
    public ResponseEntity<?> businessCancel(@RequestBody BusinessCancelRequest request) {
        if (!fundInService.canCancelCase(request)) {
            return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(BaseResult.body(null, ResultType.BUSINESS_ERROR).withMessage("此案件不能撤销！"));
        } else {
            return ResponseEntity.ok(fundInService.cancelBusiness(request));
        }
    }

    @ApiOperation("业务作废后通知已打印")
    @PutMapping("/{tsCode}/cancelHasPrinted")
    public ResponseEntity<?> cancelHasPrinted(@PathVariable long tsCode) {
        return ResponseEntity.ok(fundInService.setRefundStatePrinted(tsCode));
    }

    @ApiOperation("查找所有入账退回")
    @GetMapping("/findFundInCancel")
    public ResponseEntity<?> findFundInCancel() {
        return ResponseEntity.ok(fundInService.findFundInCancel());
    }

    @PostMapping("/refundUploadFiles")
    @ApiOperation("退款上传要件")
    public ResponseEntity<?> refundUploadFiles(@RequestBody @Valid RefundUploadFilesRequest refundUploadFilesRequest) {
        BaseResult result = fundInService.updateRefundFiels(refundUploadFilesRequest);
        if (result.getResultType() == ResultType.BUSINESS_SUCCESS) {
            return ResponseEntity.ok(BaseResult.ok("ok"));
        } else {
            return ResponseEntity.status(HttpStatus.CONFLICT).body(result);
        }
    }
}
